﻿#pragma once
#include "oatpp/parser/json/mapping/ObjectMapper.hpp"
#include "oatpp/web/server/api/ApiController.hpp"
#include "oatpp/web/mime/multipart/Multipart.hpp"
#include "oatpp/core/macro/codegen.hpp"
#include "../dto/DeviceDto.h"
#include "../dto/CountDto.h"
#include "../dto/DeviceListDto.h"
#include "../vo/DeviceVo.h"
#include "../service/DeviceService.h"
#include "../ai/Broadcast.h"
#include "../AiBox.h"
#include "../util/SystemHelper.h"

#include OATPP_CODEGEN_BEGIN(ApiController)

/**
 * 设备控制器
 */
class DeviceController : public oatpp::web::server::api::ApiController {
public:
	DeviceController(const std::shared_ptr<ObjectMapper>& objectMapper)
		: oatpp::web::server::api::ApiController(objectMapper)
	{}

	/*
	* 设备图片预览
	*/
	ENDPOINT("GET", "/device/lastImage", getDeviceImage,
		QUERY(String, id))
	{
		std::string path = SystemHelper::get_mutable_instance().GetDeviceImagePath(id, id);
		if (!FileUtil::Exists(path) || FileUtil::IsDir(path))
		{
			return ResponseFactory::createResponse(Status::CODE_404, "invalid path:" + path);
		}

		std::string content = FileUtil::Read(path);
		return createResponse(Status::CODE_200, content);
	}

	/*
	* 设备添加
	*/
	ENDPOINT("POST", "/device/add", addDevice,
		HEADER(String, authorization, "Authorization"),
		BODY_DTO(Object<DeviceVo>, vo)) {

		// 返回操作结果
		auto result = SimpleDto::createShared();
		result->error = -1;
		result->description = "服务器内部错误!";

		// 查找用户信息
		if (SystemConfig::get_mutable_instance().GetBoxConf().GetUser().GetToken() !=
			TextUtil::get_mutable_instance().GetToken(authorization.getValue("")))
		{
			result->description = "无效令牌!";
			return createDtoResponse(Status::CODE_200, result);
		}

		// 获取设备信息
		DeviceInfo device;
		device.SetId(vo->id.getValue(""));
		device.SetName(vo->name.getValue(""));
		device.SetRtspUrl(vo->rtspUrl.getValue(""));
		device.SetUsername(vo->username.getValue(""));
		device.SetPassword(vo->password.getValue(""));
		device.SetManufacture(vo->manufacture.getValue(""));
		device.SetEnabled(vo->enabled.getValue(1));
		device.SetFrameGap(vo->frameGap.getValue(25));
		device.SetStartTime(vo->startTime.getValue("00:00:00"));
		device.SetEndTime(vo->endTime.getValue("23:59:59"));
		device.SetParams(vo->params.getValue(""));
		device.SetSilence(vo->silence.getValue(5));

		// 参数校验
		if (device.GetId().empty() || device.GetName().empty() || device.GetRtspUrl().empty())
		{
			result->description = "请填写设备参数!";
			return createDtoResponse(Status::CODE_200, result);
		}

		// 新增设备信息
		DeviceService deviceService;
		deviceService.Add(device);

		// 返回操作结果
		result->error = 0;
		result->description = "success";
		result->value = device.GetId();
		return createDtoResponse(Status::CODE_200, result);
	}

	/*
	* 设备更新
	*/
	ENDPOINT("PUT", "/device/update", updateDevice,
		HEADER(String, authorization, "Authorization"),
		BODY_DTO(Object<DeviceVo>, vo)) {

		// 返回操作结果
		auto result = SimpleDto::createShared();
		result->error = -1;
		result->description = "服务器内部错误!";

		// 查找用户信息
		if (SystemConfig::get_mutable_instance().GetBoxConf().GetUser().GetToken() !=
			TextUtil::get_mutable_instance().GetToken(authorization.getValue("")))
		{
			result->description = "无效令牌!";
			return createDtoResponse(Status::CODE_200, result);
		}

		// 获取设备信息
		DeviceInfo device;
		device.SetId(vo->id.getValue(""));
		device.SetName(vo->name.getValue(""));
		device.SetRtspUrl(vo->rtspUrl.getValue(""));
		device.SetUsername(vo->username.getValue(""));
		device.SetPassword(vo->password.getValue(""));
		device.SetManufacture(vo->manufacture.getValue(""));
		device.SetEnabled(vo->enabled.getValue(1));
		device.SetFrameGap(vo->frameGap.getValue(25));
		device.SetStartTime(vo->startTime.getValue("00:00:00"));
		device.SetEndTime(vo->endTime.getValue("23:59:59"));
		device.SetParams(vo->params.getValue(""));
		device.SetSilence(vo->silence.getValue(5));

		// 参数校验
		if (device.GetId().empty() || device.GetName().empty() || device.GetRtspUrl().empty())
		{
			result->description = "请填写设备参数!";
			return createDtoResponse(Status::CODE_200, result);
		}

		// 更新设备
		DeviceService deviceService;
		if (!deviceService.Update(device))
		{
			result->description = "更新设备参数失败!";
			return createDtoResponse(Status::CODE_200, result);
		}

		// 返回操作结果
		result->error = 0;
		result->description = "success";
		return createDtoResponse(Status::CODE_200, result);
	}

	/*
	* 设备更新
	*/
	ENDPOINT("PUT", "/device/setParams", setDevParams,
		HEADER(String, authorization, "Authorization"),
		BODY_DTO(Object<DeviceVo>, vo)) {

		// 返回操作结果
		auto result = SimpleDto::createShared();
		result->error = -1;
		result->description = "服务器内部错误!";

		// 查找用户信息
		if (SystemConfig::get_mutable_instance().GetBoxConf().GetUser().GetToken() !=
			TextUtil::get_mutable_instance().GetToken(authorization.getValue("")))
		{
			result->description = "无效令牌!";
			return createDtoResponse(Status::CODE_200, result);
		}

		// 获取设备信息
		DeviceInfo device;
		device.SetId(vo->id.getValue(""));
		device.SetParams(vo->params.getValue(""));

		// 参数校验
		if (device.GetId().empty())
		{
			result->description = "请填写设备编码!";
			return createDtoResponse(Status::CODE_200, result);
		}

		// 更新设备
		DeviceService deviceService;
		if (!deviceService.UpdateParam(device))
		{
			result->description = "更新设备参数失败!";
			return createDtoResponse(Status::CODE_200, result);
		}

		// 返回操作结果
		result->error = 0;
		result->description = "success";
		return createDtoResponse(Status::CODE_200, result);
	}

	/*
	* 删除设备
	*/
	ENDPOINT("DELETE", "/device/delete", deleteDevice,
		HEADER(String, authorization, "Authorization"),
		QUERY(String, id)) {

		// 返回操作结果
		auto result = SimpleDto::createShared();
		result->error = -1;
		result->description = "服务器内部错误!";

		// 查找用户信息
		if (SystemConfig::get_mutable_instance().GetBoxConf().GetUser().GetToken() !=
			TextUtil::get_mutable_instance().GetToken(authorization.getValue("")))
		{
			result->description = "无效令牌!";
			return createDtoResponse(Status::CODE_200, result);
		}

		// 设备信息
		DeviceInfo device;
		device.SetId(id.getValue(""));

		// 删除设备
		DeviceService deviceService;
		if (deviceService.Find(device))
		{
			if (!device.GetImageUrl().empty())
			{
				std::string path = SystemHelper::get_mutable_instance().GetDeviceImagePath(device.GetId(), device.GetId());
				Box::get_mutable_instance().GetFileClear()->AddFile(path);
			}
			deviceService.Delete(device);
		}
		Box::get_mutable_instance().GetFileClear()->AddDevice(device.GetId());

		// 返回操作结果
		result->error = 0;
		result->description = "success";
		result->value = device.GetId();
		return createDtoResponse(Status::CODE_200, result);
	}

	/*
	* 删除设备
	*/
	ENDPOINT("DELETE", "/device/clear", clearDevice,
		HEADER(String, authorization, "Authorization")) {

		// 返回操作结果
		auto result = SimpleDto::createShared();
		result->error = -1;
		result->description = "服务器内部错误!";

		// 查找用户信息
		if (SystemConfig::get_mutable_instance().GetBoxConf().GetUser().GetToken() !=
			TextUtil::get_mutable_instance().GetToken(authorization.getValue("")))
		{
			result->description = "无效令牌!";
			return createDtoResponse(Status::CODE_200, result);
		}

		// 删除设备
		DeviceService deviceService;
		while (true)
		{
			std::vector<DeviceInfo> devices;
			deviceService.FindPage(0, 30, devices);
			if (devices.size() <= 0)
			{
				break;
			}
			for (size_t index = 0; index < devices.size(); ++index)
			{
				if (!devices[index].GetImageUrl().empty())
				{
					std::string path = SystemHelper::get_mutable_instance().GetDeviceImagePath(devices[index].GetId(), devices[index].GetId());
					Box::get_mutable_instance().GetFileClear()->AddFile(path);
				}
				deviceService.Delete(devices[index]);
				Box::get_mutable_instance().GetFileClear()->AddDevice(devices[index].GetId());
			}
		}

		// 返回操作结果
		result->error = 0;
		result->description = "success";
		return createDtoResponse(Status::CODE_200, result);
	}

	/*
	* 获取设备数量
	*/
	ENDPOINT("GET", "/device/count", getDeviceCount,
		HEADER(String, authorization, "Authorization"),
		REQUEST(std::shared_ptr<IncomingRequest>, request)) {

		// 获取筛选参数
		std::string id = request->getQueryParameter("id").getValue("");
		std::string enabled = request->getQueryParameter("enabled").getValue("");

		// 返回操作结果
		auto result = CountDto::createShared();
		result->error = -1;
		result->description = "服务器内部错误!";

		// 查找用户信息
		if (SystemConfig::get_mutable_instance().GetBoxConf().GetUser().GetToken() !=
			TextUtil::get_mutable_instance().GetToken(authorization.getValue("")))
		{
			result->description = "无效令牌!";
			return createDtoResponse(Status::CODE_200, result);
		}

		// 查询设备数量
		DeviceService deviceService;
		int count = deviceService.Count(id, enabled);

		// 返回操作结果
		result->error = 0;
		result->description = "success";
		result->value = count;
		return createDtoResponse(Status::CODE_200, result);
	}

	/**
	 * 查询设备列表
	 */
	ENDPOINT("GET", "/device/list", listDevice,
		HEADER(String, authorization, "Authorization"),
		QUERY(Int32, pageIndex),
		QUERY(Int32, pageSize),
		REQUEST(std::shared_ptr<IncomingRequest>, request)) {

		// 获取筛选参数
		std::string id = request->getQueryParameter("id").getValue("");
		std::string enabled = request->getQueryParameter("enabled").getValue("");

		// 返回操作结果
		auto result = DeviceListDto::createShared();
		result->error = -1;
		result->description = "服务器内部错误!";

		// 查找用户信息
		if (SystemConfig::get_mutable_instance().GetBoxConf().GetUser().GetToken() !=
			TextUtil::get_mutable_instance().GetToken(authorization.getValue("")))
		{
			result->description = "无效令牌!";
			return createDtoResponse(Status::CODE_200, result);
		}

		// 查询设备信息
		int index = (pageIndex.getValue(1) - 1) * pageSize.getValue(10);
		int size = pageSize.getValue(10);

		std::vector<DeviceInfo> devices;
		DeviceService deviceService;
		deviceService.FindPage(index, size, id, enabled, devices);

		// 初始化空列表
		oatpp::List<oatpp::Object<DeviceVo>> items({});

		// 填充设备列表
		for (size_t index = 0; index < devices.size(); ++index)
		{
			auto device = DeviceVo::createShared();
			device->id = devices[index].GetId();
			device->name = devices[index].GetName();
			device->rtspUrl = devices[index].GetRtspUrl();
			device->username = devices[index].GetUsername();
			device->password = devices[index].GetPassword();
			device->manufacture = devices[index].GetManufacture();
			device->enabled = devices[index].GetEnabled();
			device->frameGap = devices[index].GetFrameGap();
			device->startTime = devices[index].GetStartTime();
			device->endTime = devices[index].GetEndTime();
			device->params = devices[index].GetParams();
			device->silence = devices[index].GetSilence();
			device->createTime = devices[index].GetCreateTime().ToNormalString();
			device->updateTime = devices[index].GetUpdateTime().ToNormalString();
			device->detectTime = devices[index].GetDetectTime().ToNormalString();
			device->lastImage = devices[index].GetLastImage();
			device->imageUrl = devices[index].GetImageUrl();
			items->emplace(items->end(), device);
		}

		// 返回设备列表
		result->error = 0;
		result->description = "success";
		result->value = items;
		return createDtoResponse(Status::CODE_200, result);
	}
};

#include OATPP_CODEGEN_END(ApiController)